package cn.brondfish.icedfish.framework.util;

import android.content.Context;
import org.apache.commons.lang3.reflect.FieldUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.util.List;
import java.util.Properties;

import cn.brondfish.icedfish.framework.annotation.AppConfig;

public class BF_PropertiesUtil<T> {
    private Context context;
    private String propertiesFileName;
    private Class<T> clazz;
    private Properties properties;

    public BF_PropertiesUtil(Context context, String propertiesFileName, Class<T> clazz) {
        this.context = context;
        this.propertiesFileName = propertiesFileName;
        this.clazz = clazz;
    }

    public File getPropertiesFile() {
        File app_storage = this.context.getFilesDir();
        String properties_file_full_path = app_storage.getAbsolutePath() + File.separator + this.propertiesFileName;
        File properties_file = new File(properties_file_full_path);
        return properties_file;
    }

    public Properties getProperties() throws IOException {
        if(this.properties == null) {
            File properties_file = getPropertiesFile();
            if (properties_file.exists()){
                InputStream properties_reader_input_stream = Files.newInputStream(properties_file.toPath());
                Properties properties = new Properties();
                properties.load(properties_reader_input_stream);
                this.properties = properties;
                return properties;
            } else {
                return null;
            }
        } else {
            return this.properties;
        }
    }

    public T parsePropertiesToObj() throws IllegalAccessException, InstantiationException, IOException {
        if(this.properties == null){
            this.properties = this.getProperties();
        }
        if(this.properties != null){
            List<Field> fields = FieldUtils.getFieldsListWithAnnotation(this.clazz, AppConfig.class);
            T obj = this.clazz.newInstance();
            for (Field field:fields) {
                AppConfig configItem = field.getAnnotation(AppConfig.class);
                if(configItem.configKey() != null || !"".equals(configItem.configKey())) {
                    String value = this.properties.getProperty(configItem.configKey());
                    if(value == null || "".equals(value)){
                        value = configItem.defaultValue();
                    }
                    field.setAccessible(true);field.set(obj,value);
                }
            }
            return obj;
        }
        return null;
    }

    public void updateProperties(T obj) throws IOException, IllegalAccessException {
        if(this.properties == null) {
            this.properties = new Properties();
        }
        List<Field> fields = FieldUtils.getFieldsListWithAnnotation(obj.getClass(), AppConfig.class);
        for (Field field : fields) {
            AppConfig configItem = field.getAnnotation(AppConfig.class);
            if (configItem != null) {
                field.setAccessible(true);
                Object value = field.get(obj);
                if(value == null){
                    value = configItem.defaultValue();
                }
                this.properties.setProperty(configItem.configKey(),String.valueOf(value));
            }
        }
        File propertiesFile = getPropertiesFile();
        OutputStream config_file_out_put_stream = Files.newOutputStream(propertiesFile.toPath());
        this.properties.store(config_file_out_put_stream, "IceFish Base Config");
    }

}
